package com.lhkj.iams.framework.webservice.interceptor;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.google.common.util.concurrent.RateLimiter;
import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.headers.Header;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.phase.PhaseInterceptorChain;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;

import javax.servlet.http.HttpServletRequest;
import javax.xml.soap.SOAPException;
import java.util.List;
import java.util.Map;

public class AuthInterceptorJAWS extends AbstractPhaseInterceptor<SoapMessage> {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private static final String USERNAME = "root";
    private static final String PASSWORD = "root";
    private Map<String, RateLimiter> rateLimiterMap = MapUtil.newConcurrentHashMap();
    private RateLimiter rateLimiter = null;

    public AuthInterceptorJAWS() {
        /*定义在那个阶段拦截*/
        super(Phase.PRE_PROTOCOL);
    }

    @Override
    public void handleMessage(SoapMessage soapMessage) throws Fault {
        List<Header> headers = null;
        String username = null;
        String password = null;
        try {
            headers = soapMessage.getHeaders();
        } catch (Exception e) {
            logger.error("获取请求头信息失败，失败信息：{}", e.getMessage());
        }
        if (headers == null) {
            throw new Fault(new IllegalArgumentException("找不到用户信息，无法验证用户信息"));
        }
        for (Header header : headers
        ) {
            SoapHeader soapHeader = (SoapHeader) header;
            /*
            WebServiceContext webServiceContext =new WebServiceContextImpl();
            MessageContext messageContext = webServiceContext.getMessageContext();
            HttpServletRequest request =(HttpServletRequest)messageContext.get(MessageContext.SERVLET_REQUEST);
            String pathInfo = request.getPathInfo();
            System.out.println("pathInfo:"+pathInfo);*/
            Message currentMessage = PhaseInterceptorChain.getCurrentMessage();
            //获取request
            HttpServletRequest request = (HttpServletRequest) currentMessage.get(AbstractHTTPDestination.HTTP_REQUEST);
            System.out.println("getHttpServletMapping:" + request.getHttpServletMapping().getServletName());
            System.out.println("getMethos:" + request.getMethod());
            System.out.println("getPathInfo:" + request.getPathInfo());
            Element element = (Element) soapHeader.getObject();
            String textContent = element.getTextContent();
            System.out.println("textContent:" + textContent);
            String baseURI = element.getBaseURI();
            System.out.println("baseURI:" + baseURI);
            NamedNodeMap attributes = element.getAttributes();
            for (int i = 0; i < attributes.getLength(); i++) {
                System.out.println("attributes的属性" + i + attributes.item(i));
            }
            currentLimit(baseURI);
            boolean limit = rateLimiter.tryAcquire();
            if (!limit) {
                throw new Fault(new IllegalArgumentException("访问过快，请稍在尝试"));
            }
            NodeList usernameNode = element.getElementsByTagName("username");
            NodeList passwordNode = element.getElementsByTagName("password");
            username = usernameNode.item(0).getTextContent();
            password = passwordNode.item(0).getTextContent();
            System.out.println(username + password);
            if (StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
                throw new Fault(new IllegalArgumentException("用户信息为空"));
            }
            if (!(username.equals(USERNAME) && password.equals(PASSWORD))) {
                SOAPException soapException = new SOAPException("认证失败");
                logger.error("用户认证失败");
                throw new Fault(soapException);
            }
        }
    }

    /**
     * 限流
     */
    public void currentLimit(String uri) {
        if (rateLimiter == null) {
            rateLimiter = RateLimiter.create(1);
            rateLimiterMap.put(uri, rateLimiter);
        }
    }
}

